package com.xinlianshiye.im.service.impl;

import com.xinlianshiye.im.dao.FriendApplicationDao;
import com.xinlianshiye.im.dao.FriendDao;
import com.xinlianshiye.im.dao.UserGroupDao;
import com.xinlianshiye.im.bean.FriendApplication;
import com.xinlianshiye.im.bean.User;
import com.xinlianshiye.im.service.FriendApplicationService;
import com.xinlianshiye.im.service.FriendService;
import com.xinlianshiye.im.service.UserService;
import com.xinlianshiye.im.utils.RedisReceiver;
import com.xinlianshiye.clouds.common.exception.WebMessageExceptionBuilder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.util.List;
import java.util.Objects;

@Service
public class FriendApplicationServiceImpl implements FriendApplicationService {

    private final FriendApplicationDao friendApplicationDao;
    private final WebMessageExceptionBuilder exceptionBuilder;
    private final FriendDao friendDao;
    private final RedisReceiver redisReceiver;
    private final UserGroupDao userGroupDao;

    public FriendApplicationServiceImpl(FriendApplicationDao friendApplicationDao, WebMessageExceptionBuilder exceptionBuilder, FriendDao friendDao, RedisReceiver redisReceiver, UserGroupDao userGroupDao) {
        this.friendApplicationDao = friendApplicationDao;
        this.exceptionBuilder = exceptionBuilder;
        this.friendDao = friendDao;
        this.redisReceiver = redisReceiver;
        this.userGroupDao = userGroupDao;
    }

    @Autowired
    private FriendService friendService;
    @Autowired
    private UserService userService;

    @Override
    public FriendApplication apply(Integer userId, Integer targetUserId, String postscript) {
        if (Objects.equals(userId, targetUserId)) {
            throw exceptionBuilder.build(500, "不能添加自己为好友");
        }
        User fromUser = userService.getOrElseThrow(userId);
        User toUser = userService.getOrElseThrow(targetUserId);

        // 判断申请好友是否已经是好友
        if (friendDao.existsByUserAndFriend(fromUser, toUser)) {
            throw exceptionBuilder.build(500, "该好友已经是你好友了");
        }
        //判断申请好友是否已经申请了该好友
        if (friendApplicationDao.existsByUserIdAndTargetUserIdAndApplyState(userId, targetUserId, FriendApplication.ApplyStateEnum.Pending)) {
            throw exceptionBuilder.build(500, "已经申请了该好友");
        }

        FriendApplication application = new FriendApplication();
        application.setUserId(userId);
        application.setTargetUserId(targetUserId);
        application.setHaveRead(true);
        application.setTargetHaveRead(false);
        application.setGroup(userGroupDao.findByUser(fromUser).get(0));
        application.setPostscript(postscript);
        application.setApplyState(FriendApplication.ApplyStateEnum.Pending);
        friendApplicationDao.save(application);

        userService.sendInit(targetUserId);
        return application;
    }

    @Override
    public FriendApplication reply(Integer id, FriendApplication.ApplyStateEnum state, String reply) {
        // 修改好友申请表信息
        FriendApplication application = getOrElseThrow(id);
        application.setApplyState(state);
        application.setHaveRead(false);
        application.setTargetHaveRead(true);
        if (StringUtils.hasText(reply)) {
            application.setReply(reply);
        }
        application = friendApplicationDao.saveAndFlush(application);
        if (state == FriendApplication.ApplyStateEnum.Agree) {
            // 给双方在好友表中添加对应的记录
            friendService.create(application);
        }
        return application;
    }

    @Override
    public List<FriendApplication> list(Integer userId) {
        List<FriendApplication> allByUserId = friendApplicationDao.findAllByUserId(userId);
        for (FriendApplication friendApplication : allByUserId) {
            read(userId, friendApplication);
        }
        return allByUserId;
    }

    private void read(Integer userId, FriendApplication friendApplication) {
        if (userId.equals(friendApplication.getUserId()) && !friendApplication.getHaveRead()) {
            friendApplication.setHaveRead(true);
            friendApplicationDao.save(friendApplication);
        }
        if (userId.equals(friendApplication.getTargetUserId()) && !friendApplication.getTargetHaveRead()) {
            friendApplication.setTargetHaveRead(true);
            friendApplicationDao.save(friendApplication);
        }
    }

    @Override
    public FriendApplication getOrElseThrow(Integer applyId) {
        return friendApplicationDao.findById(applyId).orElseThrow(() -> exceptionBuilder.build(1, "数据不存在"));
    }
}
